import React from 'react';
import Map from 'ol/Map';
import View from 'ol/View';
import LayerVector from 'ol/layer/Vector';
import SourceVector from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import { defaults } from 'ol/control';
// import 'ol/ol.css';
import { Fill, Stroke, Style, Icon } from 'ol/style';
import {Tile as TileLayer} from 'ol/layer';
import { fromLonLat, transform} from 'ol/proj';
import Feature from 'ol/Feature';
import Point from 'ol/geom/Point';
import { OSM } from 'ol/source';
import XYZ from 'ol/source/XYZ';
import { Modify } from 'ol/interaction';
import ChinaContryBorder from "./json/ChinaContryBorder.json";
import styles from './styles.less';
import TdtSearch from './TdtSearch';
import Popup from './ol-popup';
import axios from 'axios';

/**
 * import map from '@/components/map';
 * 添加 修改坐标位置
 * this.$map.updateLocation({location:[106.103131,30.308554]})
 *
 * 地图添加点  Object or Array
 * this.$map.addVectorPoint([
 *  {location:[106.103131,30.308554],icon:''}
 *  ])
 *
   <map
    childEvevnt={map=>this.$map = map}
    getLocation={(location)=>{
      获取更新后坐标
    }}
    getLocationInfo={(info)=>{
      获取更新位置详细信息
    }}
   />
 */
const defaultCenterLocation = [114.16546,22.27534];
const defaultZoom = 13;

export default class MapModule extends React.PureComponent {
  constructor(props) {
    super(props);
    props.childEvevnt && props.childEvevnt(this);
    this.state = {
      mapCenter: defaultCenterLocation,
      zoom: defaultZoom,
    }
  }

  componentDidMount() {
    this.mapInitLoad();
  }

  mapInitLoad=()=>{
    const { mapCenter,zoom } = this.state;
    this.map_layer = new TileLayer({
      visible: true,
      source: new XYZ({
          url: 'http://www.google.cn/maps/vt?lyrs=r@189&gl=cn&x={x}&y={y}&z={z}'
      })
    });
    this.raster = new TileLayer({
      source: new OSM(),
    });

    this.map_view = new View({
      center: fromLonLat(mapCenter),
      zoom: zoom,
    })

    //创建地图组件
    this.map = new Map({
      view: this.map_view,
      layers: [
        this.raster,
        this.map_layer,
      ],
      controls: defaults({
        attributionOptions: ({
          collapsible: false
        }),
        attribution: false,
        rotate: false,
        zoom: false
      }),
      target: this.mapDom
    });

    this.map.on("click",  (e)=> {
      this.map.forEachFeatureAtPixel(e.pixel,  (feature)=> {
        console.log(feature.values_,"feature");
        let values = feature.values_;
        if(!values.data) return false;
        this.mapPopup(transform(e.coordinate, 'EPSG:3857','EPSG:4326' ),values);
        return feature;
      });

    });

  }

  /**
   * 添加更新坐标位置
   *
   */
  updateLocation = (options={}) =>{
    if(!this.point_layer){
      this.pointSourceVector = new SourceVector();
      this.point_layer = new LayerVector({
        source: this.pointSourceVector,
        overlaps: false,
        wrapX: false,
        zIndex:10,
      })
      this.map.addLayer(this.point_layer)
      let modify = new Modify({
        hitDetection: this.point_layer,
        source: this.pointSourceVector,
      });
      modify.on(['modifystart', 'modifyend'], (evt)=> {
        // 拖拽后坐标
        let extent = evt.features.item(0).getGeometry().getCoordinates();
        this.last_location = transform(extent, 'EPSG:3857' ,'EPSG:4326');
        const {getLocation,getLocationInfo} =this.props;
        if(getLocation)getLocation(this.last_location);
        if(getLocationInfo)this.getLocationInfo(this.last_location);
        this.mapDom.style.cursor = evt.type === 'modifystart' ? 'move' : 'pointer';
      });
      let overlaySource = modify.getOverlay().getSource();
      overlaySource.on(['addfeature', 'removefeature'], (evt)=> {
        this.mapDom.style.cursor = evt.type === 'addfeature' ? 'pointer' : '';
      });

      this.map.addInteraction(modify);
    }

    !options.clear&&this.point_layer.getSource().clear();
      this.handleSetMapView({location:options.location})

      let newFeature = new Feature({
      data: options.info,
      geometry: new Point(fromLonLat(options.location || this.state.mapCenter)),
      type:options.type
    });
    let url = options.icon?options.icon:require('./image/marker-location.png');
    let iconStyle = new Style({
      image: new Icon(
        ({
          anchor: [0.5, 28],
          anchorXUnits: "fraction",
          anchorYUnits: "pixels",
          src: url,
        })
      )
    });

    newFeature.setStyle(iconStyle);

    //将当前要素添加到矢量数据源中
    this.point_layer.getSource().addFeature(newFeature);
    // this.point_layer.setVisible(true);
  }

  getLocationInfo = (location) =>{
    axios.get('http://api.tianditu.gov.cn/geocoder', {
      params: {
        postStr:{
          lon:location[0],
          lat:location[1],
          ver:1,
        },
        type:'geocode',
        tk:'fea2e56773d1e30eefa38b6a6d863acf'
      }
    })
      .then((response)=> {
        let data = response.data;
        const {getLocationInfo} =this.props;
        if(getLocationInfo)getLocationInfo(data.result);
      })
      .catch((error)=> {
        console.log(error);
      });
  }

  /**
   * 添加矢量要素点
   * @param options{
   *   location:[经度，纬度]，
   *   icon:图标，
   * }
   */

  addVectorPoint =(options)=> {
    if(!this.point_more_layer){
      this.point_more_layer = new LayerVector({
        source: new SourceVector(),
        overlaps: false,
        wrapX: false,
        zIndex:10,
      })
      this.map.addLayer(this.point_more_layer)
    }
    this.point_more_layer.getSource().clear();
    if(Array.isArray(options)){
      options.forEach(item=>{
        this.hanleaddVectorPoint(item);
      })
    }else {
      this.hanleaddVectorPoint(options);
    }
  }

  hanleaddVectorPoint = (options) =>{
    if(!options)return false;

      let newFeature = new Feature({
      data: options,
      geometry: new Point(fromLonLat(options.location)),
      type:options.type
    });
    let url = options.icon?options.icon:require('./image/marker-icon.png');
    let iconStyle = new Style({
      image: new Icon(
        ({
          anchor: [0.5, 46],
          anchorXUnits: "fraction",
          anchorYUnits: "pixels",
          src: url,
        })
      )
    });

    newFeature.setStyle(iconStyle);

    //将当前要素添加到矢量数据源中
    this.point_more_layer.getSource().addFeature(newFeature);
    // this.point_layer.setVisible(true);
  }

  /**
   * 中国边界
   */
  setChinaContryBorder =()=>{
    const chinaContryBorder = new LayerVector({
      title: 'add Layer',
      source: new SourceVector({
        features: new GeoJSON().readFeatures(ChinaContryBorder, {
          dataProjection: 'EPSG:4326',
          featureProjection: 'EPSG:3857'
        }),
        wrapX: false
      }),
      style: new Style({
        fill: new Fill({
          //矢量图层填充颜色，以及透明度
          color: "rgba(0,0,0,0)"
        }),
        stroke: new Stroke({
          //边界样式
          color: "rgba(226,21,21,0.6)",
          width: 2
        }),
      })
    });
    this.map.addLayer(chinaContryBorder);
  }

  /**
   * Popup
   */
  mapPopup = (coordinate,values={})=>{
    this.setState({
      locationInfo : values.data,
      // visible:values.datatype || 'detail'
    })
    this.Popup = new Popup({ map:this.map });
    this.map.addOverlay(this.Popup);
    this.Popup.show(coordinate,this.popup);
  }

  mapPopupClose = ()=> {
    this.Popup && this.Popup.hide();
  };

  /**
   * 设置 center坐标 zoom
   */
  handleSetMapView = (options) =>{
    const {mapCenter,zoom} = this.state;
    options && this.map_view.animate({
      center: fromLonLat(options.location?options.location:mapCenter),
      zoom: options.zoom?options.zoom:zoom,
      duration: 1000
    });
  }

  /**
   * 设置 zoom 放大缩小  +1 -1
   */
  setMapZoom = (zoom)=> {
    this.map_view.animate({
      zoom: this.map_view.getZoom() +zoom,
      duration: 500
    });
  }

  /*
  *清空坐标点
  */
  clearPointn=()=> {
    if(this.point_layer) this.point_layer.getSource().clear();
    if(this.point_more_layer) this.point_more_layer.getSource().clear();
  }

  handleLocationInfo = (info)=>{
    info.location = info.lonlat.split(' ');
    this.updateLocation(info);
    this.handleSetMapView({location:info.location,zoom:14})
    const {getLocation,getLocationInfo} = this.props;
    getLocation&&getLocation(info.location)
    if(getLocationInfo)this.getLocationInfo(info.location);
  }

  handleAllLocationInfo = (info)=>{
    if(info.pois){
    info.pois.forEach(item=>{
        item.location = item.lonlat.split(' ');
      })
    }
    this.addVectorPoint(info.pois || []);
  }
  render() {
    const {locationInfo} = this.state;
    const {style} = this.props;
    return <div className={styles.mapWrap} style={style}>
      <div ref={ref =>this.mapDom = ref} className={styles.map}></div>
      {/*<TdtSearch*/}
      {/*  className={styles.tdtSearch}*/}
      {/*  getLocationInfo={(info)=>this.handleLocationInfo(info)}*/}
      {/*  getAllLocationInfo={(info)=>this.handleAllLocationInfo(info)}*/}
      {/*  $map={this}*/}
      {/*/>*/}
      <div ref={ref=>this.popup =ref} className={styles.olPopup}>
        {
          locationInfo&&<div>
            <div className={styles.header}>
              {/*<img src={require('@/assets/images/AMap/qiyeWarning/popup-location.svg')} alt="" />*/}
              <span>{locationInfo.name}</span>
              {/*<img className={styles.olPopupCloser} onClick={this.mapPopupClose} src={require('@/assets/images/AMap/qiyeWarning/popup-closer.svg')} alt="" />*/}
            </div>
            <div className={styles.content}>
              {locationInfo.address}
            </div>
          </div>
        }
      </div>
      {/*<div className={styles.toolbar}>*/}
      {/*  <img onClick={()=>this.handleSetMapView({location:defaultCenterLocation,zoom:defaultZoom})} src={require('@/assets/images/AMap/mapToolbar/map-default-pos.svg')} alt="" />*/}
      {/*  <img onClick={()=>this.setMapZoom(+1)} src={require('@/assets/images/AMap/mapToolbar/map-zoom-in.svg')} alt="" />*/}
      {/*  <img onClick={()=>this.setMapZoom(-1)} src={require('@/assets/images/AMap/mapToolbar/map-zoom-out.svg')} alt="" />*/}
      {/*</div>*/}
    </div>
  }
}
